﻿using CRedis.Client;
using CRedis.Client.Entities;
using CRedis.Client.Logic;
using CRedis.Client.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RedisClientTest
{
    public class MyRedisCacheProvider : ICacheProvider
    {
        ICacheProvider _cacheProvider;
        private RedisCluster _cluster
        {
            get
            {
                return this._factory.GetCluster(this._clusterName);
            }
        }
        private string _clusterName;
        private ClusterFactory _factory;
        public MyRedisCacheProvider(string clusterName)
        {
            _clusterName = clusterName;
            this._factory = ClusterFactory.Create();
            _cacheProvider = CacheFactory.GetPorvider(clusterName);
        }
        public void AddItemToList(string key, string value)
        {
            _cacheProvider.AddItemToList(key, value);
        }

        public void AddItemToSet(string key, string item, ref bool sucess)
        {
            throw new NotImplementedException();
        }

        public void AddItemToSet(string key, string item)
        {
            throw new NotImplementedException();
        }

        public bool AddItemToSortedSet(string key, string value, long score)
        {
            throw new NotImplementedException();
        }

        public bool AddItemToSortedSet(string key, string value, double score)
        {
            throw new NotImplementedException();
        }

        public bool AddItemToSortedSet(string key, string value)
        {
            throw new NotImplementedException();
        }

        public void AddRangeToList(string key, List<string> values)
        {
            throw new NotImplementedException();
        }

        public void AddRangeToSet(string key, List<string> items, ref long successCount)
        {
            throw new NotImplementedException();
        }

        public void AddRangeToSet(string key, List<string> items)
        {
            throw new NotImplementedException();
        }

        public bool AddRangeToSortedSet(string key, List<string> values, long score)
        {
            throw new NotImplementedException();
        }

        public bool AddRangeToSortedSet(string key, List<string> values, double score)
        {
            throw new NotImplementedException();
        }

        public long AddRangeToSortedSet(string key, List<KeyValuePair<string, long>> valuesscores)
        {
            throw new NotImplementedException();
        }

        public long AddRangeToSortedSet(string key, List<KeyValuePair<string, double>> valuesscores)
        {
            throw new NotImplementedException();
        }

        public long AddRangeToSortedSet(string key, List<KeyValuePair<byte[], long>> valuesscores)
        {
            throw new NotImplementedException();
        }

        public long AddRangeToSortedSet(string key, List<KeyValuePair<byte[], double>> valuesscores)
        {
            throw new NotImplementedException();
        }

        public string BlockingDequeueItemFromList(string key, TimeSpan? timeOut)
        {
            throw new NotImplementedException();
        }

        public string BlockingPopItemFromList(string key, TimeSpan? timeOut)
        {
            throw new NotImplementedException();
        }

        public string BlockingRemoveStartFromList(string key, TimeSpan? timeOut)
        {
            throw new NotImplementedException();
        }

        public bool ContainsKey(string key)
        {
            throw new NotImplementedException();
        }

        public long Decr(string key)
        {
            throw new NotImplementedException();
        }

        public long DecrBy(string key, int count)
        {
            throw new NotImplementedException();
        }

        public bool Del(string key)
        {
            throw new NotImplementedException();
        }

        public string DequeueItemFromList(string key)
        {
            throw new NotImplementedException();
        }

        public void EnqueueItemOnList(string key, string value)
        {
            throw new NotImplementedException();
        }

        public bool ExpireEntryIn(string key, TimeSpan expireIn)
        {
            throw new NotImplementedException();
        }

        public T Get<T>(string key)
        {
            throw new NotImplementedException();
        }

        public Dictionary<string, string> GetAllEntriesFromHash(string key)
        {
            throw new NotImplementedException();
        }

        public List<string> GetAllItemsFromList(string key)
        {
            throw new NotImplementedException();
        }

        public HashSet<string> GetAllItemsFromSet(string key)
        {
            throw new NotImplementedException();
        }

        public List<string> GetAllItemsFromSortedSet(string key)
        {
            throw new NotImplementedException();
        }

        public List<string> GetAllItemsFromSortedSetDesc(string key)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetAllWithScoresFromSortedSet(string key)
        {
            throw new NotImplementedException();
        }

        public string GetAndSetEntry(string key, string value)
        {
            throw new NotImplementedException();
        }

        public long GetHashCount(string key)
        {
            throw new NotImplementedException();
        }

        public List<string> GetHashKeys(string key)
        {
            throw new NotImplementedException();
        }

        public List<string> GetHashValues(string key)
        {
            throw new NotImplementedException();
        }

        public string GetItemFromList(string key, int listIndex)
        {
            throw new NotImplementedException();
        }

        public long GetItemIndexInSortedSet(string key, string value)
        {
            throw new NotImplementedException();
        }

        public long GetItemIndexInSortedSetDesc(string key, string value)
        {
            throw new NotImplementedException();
        }

        public double GetItemScoreInSortedSet(string key, string value)
        {
            throw new NotImplementedException();
        }

        public long GetListCount(string key)
        {
            throw new NotImplementedException();
        }

        public CRedis.Third.Redis.RedisClient GetNonshardingRedis()
        {
            throw new NotImplementedException();
        }

        public CRedis.Client.Pipeline.CachePipeline GetPipeline()
        {
            throw new NotImplementedException();
        }

        public string GetRandomItemFromSet(string key)
        {
            throw new NotImplementedException();
        }
        public List<string> GetRandomItemFromSet(string key,int count)
        {
            return this.GetAction<List<string>>((MyRedisServer server) => server.GetRandomItemFromSet(key,count), key,count);
        }
        private T GetAction<T>(Func<MyRedisServer, T> func, string key,int count)
        {
            RedisGroup group = this._cluster.GetGroupByKey(key);
            return this.GetAction<T>(func, group);
        }

        private T GetAction<T>(Func<MyRedisServer, T> func, RedisGroup group)
        {
            T resunt = default(T);
            for (int i = 0; i < group.ReadServers.Count; i++)
            {
                MyRedisServer server = null;
                try
                {
                    server = (MyRedisServer)group.GetCurrentServer();
                    resunt = func(server);
                    break;
                }
                catch (System.Exception ex)
                {
                    this.WriteError("geterror", ex, group.Cluster.Name, server);
                    if (i == group.ReadServers.Count - 1)
                    {
                        throw ex;
                    }
                }
            }
            return resunt;
        }

        private void WriteError(string title, System.Exception ex, string clusterName, RedisServer server)
        {
            try
            {
                System.Collections.Generic.Dictionary<string, string> tags = new System.Collections.Generic.Dictionary<string, string>();
                tags.Add("clustername", clusterName);
                if (server != null)
                {
                    tags.Add("serverip", server.IPAddress);
                    tags.Add("serverport", server.Port.ToString());
                    tags.Add("dbnumber", server.DBNumber.ToString());
                }
                RedisLogger.Error(title, ex, tags);
            }
            catch
            {
            }
        }

        public List<string> GetRangeFromList(string key, int startingFrom, int endingAt)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedList(string key, int startingFrom, int take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSet(string key, int from, int to)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByHighestScore(string key, long fromScore, long toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByHighestScore(string key, double fromScore, double toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByHighestScore(string key, long fromScore, long toScore)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByHighestScore(string key, double fromScore, double toScore)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByHighestScore(string key, string fromStringScore, string toStringScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByHighestScore(string key, string fromStringScore, string toStringScore)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByLowestScore(string key, long fromScore, long toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByLowestScore(string key, double fromScore, double toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByLowestScore(string key, long fromScore, long toScore)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByLowestScore(string key, double fromScore, double toScore)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByLowestScore(string key, string fromStringScore, string toStringScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByLowestScore(string key, string fromStringScore, string toStringScore)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetByScore(string key, int from, int to)
        {
            throw new NotImplementedException();
        }

        public List<string> GetRangeFromSortedSetDesc(string key, int from, int to)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSet(string key, int fromRank, int toRank)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, long fromScore, long toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, double fromScore, double toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, long fromScore, long toScore)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, double fromScore, double toScore)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, string fromStringScore, string toStringScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, string fromStringScore, string toStringScore)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, long fromScore, long toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, double fromScore, double toScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, long fromScore, long toScore)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, double fromScore, double toScore)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, string fromStringScore, string toStringScore, int? skip, int? take)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, string fromStringScore, string toStringScore)
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, double> GetRangeWithScoresFromSortedSetDesc(string key, int fromRank, int toRank)
        {
            throw new NotImplementedException();
        }

        public long GetSetCount(string key)
        {
            throw new NotImplementedException();
        }

        public List<string> GetSortedEntryValues(string key, int startingFrom, int take)
        {
            throw new NotImplementedException();
        }

        public List<string> GetSortedItemsFromList(string key, CRedis.Third.Redis.SortOptions sortOptions)
        {
            throw new NotImplementedException();
        }

        public long GetSortedSetCount(string key, long fromScore, long toScore)
        {
            throw new NotImplementedException();
        }

        public long GetSortedSetCount(string key, double fromScore, double toScore)
        {
            throw new NotImplementedException();
        }

        public long GetSortedSetCount(string key, string fromStringScore, string toStringScore)
        {
            throw new NotImplementedException();
        }

        public long GetSortedSetCount(string key)
        {
            throw new NotImplementedException();
        }

        public TimeSpan GetTimeToLive(string key)
        {
            throw new NotImplementedException();
        }

        public string GetValue(string key)
        {
            throw new NotImplementedException();
        }

        public string GetValueFromHash(string key, string hashKey)
        {
            throw new NotImplementedException();
        }

        public List<T> GetValues<T>(List<string> keys)
        {
            throw new NotImplementedException();
        }

        public List<string> GetValues(List<string> keys)
        {
            throw new NotImplementedException();
        }

        public List<string> GetValuesFromHash(string key, params string[] hashKeys)
        {
            throw new NotImplementedException();
        }

        public bool HashContainsEntry(string key, string hashKey)
        {
            throw new NotImplementedException();
        }

        public long Incr(string key)
        {
            throw new NotImplementedException();
        }

        public long IncrBy(string key, int count)
        {
            throw new NotImplementedException();
        }

        public double IncrementItemInSortedSet(string key, string value, long incrementBy)
        {
            throw new NotImplementedException();
        }

        public double IncrementItemInSortedSet(string key, string value, double incrementBy)
        {
            throw new NotImplementedException();
        }

        public long IncrementValueInHash(string key, string hashKey, long incrementBy)
        {
            throw new NotImplementedException();
        }

        public long IncrementValueInHash(string key, string hashKey, int incrementBy)
        {
            throw new NotImplementedException();
        }

        public string PopItemFromList(string key)
        {
            throw new NotImplementedException();
        }

        public string PopItemFromSet(string key)
        {
            throw new NotImplementedException();
        }

        public string PopItemWithHighestScoreFromSortedSet(string key)
        {
            throw new NotImplementedException();
        }

        public string PopItemWithLowestScoreFromSortedSet(string key)
        {
            throw new NotImplementedException();
        }

        public void PrependItemToList(string key, string value)
        {
            throw new NotImplementedException();
        }

        public void PrependRangeToList(string key, List<string> values)
        {
            throw new NotImplementedException();
        }

        public void PushItemToList(string key, string value)
        {
            throw new NotImplementedException();
        }

        public int ReceiveTimeout
        {
            set { throw new NotImplementedException(); }
        }

        public bool Remove(string key)
        {
            throw new NotImplementedException();
        }

        public void RemoveAllFromList(string key)
        {
            throw new NotImplementedException();
        }

        public string RemoveEndFromList(string key)
        {
            throw new NotImplementedException();
        }

        public bool RemoveEntryFromHash(string key, string hashKey)
        {
            throw new NotImplementedException();
        }

        public long RemoveItemFromList(string key, string value, int noOfMatches)
        {
            throw new NotImplementedException();
        }

        public long RemoveItemFromList(string key, string value)
        {
            throw new NotImplementedException();
        }

        public void RemoveItemFromSet(string key, string item)
        {
            throw new NotImplementedException();
        }

        public bool RemoveItemFromSortedSet(string key, string value)
        {
            throw new NotImplementedException();
        }

        public long RemoveRangeFromSortedSet(string key, int minRank, int maxRank)
        {
            throw new NotImplementedException();
        }

        public long RemoveRangeFromSortedSetByScore(string key, long fromScore, long toScore)
        {
            throw new NotImplementedException();
        }

        public long RemoveRangeFromSortedSetByScore(string key, double fromScore, double toScore)
        {
            throw new NotImplementedException();
        }

        public string RemoveStartFromList(string key)
        {
            throw new NotImplementedException();
        }

        public int SendTimeout
        {
            set { throw new NotImplementedException(); }
        }

        public bool Set<T>(List<KeyValuePair<string, T>> keysvalues)
        {
            throw new NotImplementedException();
        }

        public bool Set<T>(string key, T value, TimeSpan expiredTime)
        {
            throw new NotImplementedException();
        }

        public bool Set<T>(string key, T value, DateTime expiredTime)
        {
            throw new NotImplementedException();
        }

        public bool Set<T>(string key, T value)
        {
            throw new NotImplementedException();
        }

        public bool SetContainsItem(string key, string item)
        {
            throw new NotImplementedException();
        }

        public void SetEntryIfExists(string key, string value, TimeSpan expireIn)
        {
            throw new NotImplementedException();
        }

        public void SetEntryIfNotExists(string key, string value, TimeSpan expireIn)
        {
            throw new NotImplementedException();
        }

        public bool SetEntryIfNotExists(string key, string value)
        {
            throw new NotImplementedException();
        }

        public bool SetEntryInHash(string key, string hashKey, string value)
        {
            throw new NotImplementedException();
        }

        public bool SetEntryInHashIfNotExists(string key, string hashKey, string value)
        {
            throw new NotImplementedException();
        }

        public void SetItemInList(string key, int listIndex, string value)
        {
            throw new NotImplementedException();
        }

        public void SetRangeInHash(string key, IEnumerable<KeyValuePair<string, string>> keyValuePairs)
        {
            throw new NotImplementedException();
        }

        public bool SortedSetContainsItem(string key, string value)
        {
            throw new NotImplementedException();
        }

        public void TrimList(string key, int keepStartingFrom, int keepEndingAt)
        {
            throw new NotImplementedException();
        }
    }
}
